package org.ru.mse10.cvis.web.bean.action;

import java.util.ArrayList;
import java.util.ResourceBundle;

import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;

import org.apache.commons.lang.StringUtils;
import org.ru.mse10.cvis.constants.UserRole;
import org.ru.mse10.cvis.entity.cv.User;
import org.ru.mse10.cvis.service.MailService;
import org.ru.mse10.cvis.service.UserService;
import org.ru.mse10.cvis.util.CommonUtil;
import org.ru.mse10.cvis.web.bean.BaseFormBean;

/**
 * The Class UserAction.
 */
@SessionScoped
@ManagedBean(name = "userAction")
public class UserAction extends BaseFormBean<User, UserService> {

	/** The user service. */
	@EJB
	private UserService userService;

	/** The mail service. */
	@EJB
	private MailService mailService;

	/** The context. */
	private final FacesContext context = FacesContext.getCurrentInstance();

	/** The bundle. */
	private final ResourceBundle bundle = context.getApplication()
			.getResourceBundle(context, "message");

	/** The user. */
	private User user;

	/** The password. */
	private String password;

	/** The confirm password. */
	private String confirmPassword;

	/** The old password. */
	private String oldPassword;

	/** The forgot password email. */
	private String forgotPasswordEmail;

	/**
	 * Inits the.
	 * 
	 * @param user
	 *            the user
	 * @return the string
	 */
	private String init(User user) {
		setTargetEntity(user);
		return null;
	}

	/**
	 * Creates the user action.
	 * 
	 * @return the string
	 */
	public String createUserAction() {
		init(new User());
		setReadonly(false);
		return "userDetails";
	}

	/**
	 * Load profile.
	 * 
	 * @return the string
	 */
	public String loadProfile() {
		setTargetEntity((User) getUser());
		setPassword(null);
		setConfirmPassword(null);
		return "userProfile";
	}

	/**
	 * Save profile.
	 * 
	 * @return the string
	 * @throws Exception
	 *             the exception
	 */
	public String saveProfile() throws Exception {
		Long userId = userService.checkLogin(getTargetEntity().getEmail(),
				oldPassword);
		if (userId == null) {
			FacesContext.getCurrentInstance().addMessage(
					"userProfileForm",
					new FacesMessage(FacesMessage.SEVERITY_ERROR, bundle
							.getString("wrongOldPassword"), null));
		} else {
			if (!StringUtils.isEmpty(password)) {
				getTargetEntity()
						.setPassword(CommonUtil.hashPassword(password));
			}
		}
		user = userService.save(getTargetEntity());
		setTargetEntity(user);
		setUser(user);
		FacesContext.getCurrentInstance().addMessage(
				"userProfileForm",
				new FacesMessage(FacesMessage.SEVERITY_INFO, bundle
						.getString("profileUpdated"), null));
		return "saveUserProfile";
	}

	/**
	 * Save.
	 */
	public void save() {
		String password = CommonUtil.generatePassword();
		getTargetEntity().setPassword(CommonUtil.hashPassword(password));
		setTargetEntity(userService.save(getTargetEntity()));
		setReadonly(true);
		String email = getTargetEntity().getEmail();
		String subject = "You have been registered in CVIS!";
		String mailText = "You have been registered in CVIS!\nTo access the system use the following credentials:\nUsername: "
				+ email + "\nPassword: " + password;
		mailService.sendUserMail(password, email, subject, mailText);
	}

	/**
	 * Open.
	 * 
	 * @param user
	 *            the user
	 * @return the string
	 */
	public String open(User user) {
		init(user);
		setReadonly(true);
		return "userDetails";

	}

	/**
	 * Gets the role values.
	 * 
	 * @return the role values
	 */
	public ArrayList<SelectItem> getRoleValues() {
		ArrayList<SelectItem> roles = new ArrayList<SelectItem>(
				UserRole.values().length);
		for (UserRole g : UserRole.values()) {
			roles.add(new SelectItem(g, g.getLabel()));
		}
		return roles;
	}

	/**
	 * Action cancel.
	 * 
	 * @return the string
	 */
	public String actionCancel() {
		if (user.getId() != null) {
			userService.refresh(user);
			return init(user);
		}
		return "home";
	}

	/**
	 * I dont use this method for now.
	 * 
	 * @return the string
	 */
	public String forgotPassword() {
		return "forgotPassword";
	}

	/**
	 * Method to send new password to user who had forgot it.
	 * 
	 * @return - just reload the same page with message in it.
	 */
	public String sendNewPassword() {
		User uniqueUser = userService.findUserByEmail(forgotPasswordEmail);
		if (uniqueUser == null) {
			FacesContext.getCurrentInstance().addMessage(
					"forgotPassForm",
					new FacesMessage(FacesMessage.SEVERITY_ERROR, bundle
							.getString("errorNotExistingEmail"), null));
		} else {
			FacesContext.getCurrentInstance().addMessage(
					"forgotPassForm",
					new FacesMessage(FacesMessage.SEVERITY_INFO, bundle
							.getString("newPasswordSend"), null));
		}
		setTargetEntity(uniqueUser);
		String password = CommonUtil.generatePassword();
		getTargetEntity().setPassword(CommonUtil.hashPassword(password));
		setTargetEntity(userService.save(getTargetEntity()));
		String subject = "Your Password was changed in CVIS!";
		String mailText = "Your profile password was changed in CVIS!\nTo access the system use the following credentials:\nUsername: "
				+ forgotPasswordEmail + "\nPassword: " + password;
		mailService.sendUserMail(password, forgotPasswordEmail, subject,
				mailText);
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.ru.mse10.cvis.web.bean.BaseFormBean#getTargetEntity()
	 */
	@Override
	public User getTargetEntity() {
		User user = super.getTargetEntity();
		if (user == null) {
			user = new User();
			setTargetEntity(user);
		}
		return user;
	}

	/**
	 * Gets the password.
	 * 
	 * @return the password
	 */
	public String getPassword() {
		return password;
	}

	/**
	 * Sets the password.
	 * 
	 * @param password
	 *            the new password
	 */
	public void setPassword(String password) {
		this.password = password;
	}

	/**
	 * Gets the confirm password.
	 * 
	 * @return the confirm password
	 */
	public String getConfirmPassword() {
		return confirmPassword;
	}

	/**
	 * Sets the confirm password.
	 * 
	 * @param confirmPassword
	 *            the new confirm password
	 */
	public void setConfirmPassword(String confirmPassword) {
		this.confirmPassword = confirmPassword;
	}

	/**
	 * Gets the old password.
	 * 
	 * @return the old password
	 */
	public String getOldPassword() {
		return oldPassword;
	}

	/**
	 * Sets the old password.
	 * 
	 * @param oldPassword
	 *            the new old password
	 */
	public void setOldPassword(String oldPassword) {
		this.oldPassword = oldPassword;
	}

	/**
	 * Gets the forgot password email.
	 * 
	 * @return the forgot password email
	 */
	public String getForgotPasswordEmail() {
		return forgotPasswordEmail;
	}

	/**
	 * Sets the forgot password email.
	 * 
	 * @param forgotPasswordEmail
	 *            the new forgot password email
	 */
	public void setForgotPasswordEmail(String forgotPasswordEmail) {
		this.forgotPasswordEmail = forgotPasswordEmail;
	}
}
